OPC Studio User's Guide and Reference
Read-Write Register Data Variables
Concepts > OPC Wizard Concepts > OPC Wizard Operation Model > Data Provision And Consumption Models > Read-Write Register Data Variables
In This Topic

General

The read-write register is a data variables that "holds" the value that is written to it by an OPC client, and the same value is then provided when the data variable is read by an OPC client (or an OPC client subscribes to it). Without further configuration, each data variable in OPC Wizard behaves essentially as a read-write register, because

However, even though the default behavior correspond to the read-write register, you usually still need to configure additional properties on the data variable, such as the data type. In most cases, you also want to define some reasonable initial data for the variable. These tasks can be done with the help of extensions methods for Data Variable Configuration.

Extension Methods for Configuration

The OPC Wizard provides extension methods that allow you to define read-write register data variables easily. This is described in the Data Variable Configuration article. Typically, you will use some overload of the ReadWrite or ReadWriteValue method to configure the data variable as the read-write register. The following example illustrates the use of the ReadWriteValue method.

.NET

// This example shows how to create a read-write data variable that behaves like a register.
// You can use any OPC UA client, including our Connectivity Explorer and OpcCmd utility, to connect to the server. 
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client, server and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-OPCStudio-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

using System;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.NodeSpace;

namespace UAServerDocExamples._UADataVariable
{
    partial class ReadWriteValue
    {
        public static void Main1()
        {
            // Instantiate the server object.
            // By default, the server will run on endpoint URL "opc.tcp://localhost:48040/".
            var server = new EasyUAServer();

            // Create a data variable that is a read-write register, defining its initial value.
            // The type of the data variable (Int32, in this case) is inferred from the initial value.
            server.Add(new UADataVariable("MyVariable").ReadWriteValue(42));

            // Start the server.
            Console.WriteLine("The server is starting...");
            server.Start();

            Console.WriteLine("The server is started.");
            Console.WriteLine();

            // Let the user decide when to stop.
            Console.WriteLine("Press Enter to stop the server...");
            Console.ReadLine();

            // Stop the server.
            Console.WriteLine("The server is stopping...");
            server.Stop();

            Console.WriteLine("The server is stopped.");
        }
    }
}
' This example shows how to create a read-write data variable that behaves like a register.
' You can use any OPC UA client, including our Connectivity Explorer and OpcCmd utility, to connect to the server. 
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
' OPC client and subscriber examples in VB.NET on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBNET .
' Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
' a commercial license in order to use Online Forums, and we reply to every post.

Imports System
Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.NodeSpace

Namespace _UADataVariable
    Partial Friend Class ReadWriteValue
        Shared Sub Main1()
            ' Instantiate the server object.
            ' By default, the server will run on endpoint URL "opc.tcp://localhost:48040/".
            Dim server = New EasyUAServer()

            ' Create a data variable that is a read-write register, defining its initial value.
            ' The type of the data variable (Int32, in this case) is inferred from the initial value.
            server.Add(New UADataVariable("MyVariable").ReadWriteValue(42))

            ' Start the server.
            Console.WriteLine("The server is starting...")
            server.Start()

            Console.WriteLine("The server is started.")
            Console.WriteLine()

            ' Let the user decide when to stop.
            Console.WriteLine("Press Enter to stop the server...")
            Console.ReadLine()

            ' Stop the server.
            Console.WriteLine("The server is stopping...")
            server.Stop()

            Console.WriteLine("The server is stopped.")
        End Sub
    End Class
End Namespace

How do you choose between these extension methods?

The following example illustrates the use of the ReadWrite method for defining a read-write register with specified initial attribute data (including status code and timestamp).

.NET

// This example shows how to create a read-write data variable that behaves like a register, specifying initial attribute
// data (including the status code and source timestamp).
// You can use any OPC UA client, including our Connectivity Explorer and OpcCmd utility, to connect to the server. 
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client, server and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-OPCStudio-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

using System;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.Generic;
using OpcLabs.EasyOpc.UA.NodeSpace;

namespace UAServerDocExamples._UADataVariable
{
    partial class ReadWrite
    {
        public static void Main1()
        {
            // Instantiate the server object.
            // By default, the server will run on endpoint URL "opc.tcp://localhost:48040/".
            var server = new EasyUAServer();

            // Create a data variable that is a read-write register, defining its initial attribute data.
            // The type of the data variable (Int32, in this case) is inferred from the initial data.
            server.Add(new UADataVariable("MyVariable").ReadWrite(new UAAttributeData<int>(
                value:42,
                UACodeBits.GoodLocalOverride,
                DateTime.UtcNow)));

            // Start the server.
            Console.WriteLine("The server is starting...");
            server.Start();

            Console.WriteLine("The server is started.");
            Console.WriteLine();

            // Let the user decide when to stop.
            Console.WriteLine("Press Enter to stop the server...");
            Console.ReadLine();

            // Stop the server.
            Console.WriteLine("The server is stopping...");
            server.Stop();

            Console.WriteLine("The server is stopped.");
        }
    }
}
' This example shows how to create a read-write data variable that behaves like a register, specifying initial attribute
' data (including the status code and source timestamp).
' You can use any OPC UA client, including our Connectivity Explorer and OpcCmd utility, to connect to the server. 
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
' OPC client and subscriber examples in VB.NET on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBNET .
' Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
' a commercial license in order to use Online Forums, and we reply to every post.

Imports System
Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.Generic
Imports OpcLabs.EasyOpc.UA.NodeSpace

Namespace _UADataVariable
    Partial Friend Class ReadWrite
        Shared Sub Main1()
            ' Instantiate the server object.
            ' By default, the server will run on endpoint URL "opc.tcp://localhost:48040/".
            Dim server = New EasyUAServer()

            ' Create a data variable that is a read-write register, defining its initial attribute data.
            ' The type of the data variable (Int32, in this case) is inferred from the initial data.
            server.Add(New UADataVariable("MyVariable").ReadWrite(New UAAttributeData(Of Integer)(
                value:=42,
                UACodeBits.GoodLocalOverride,
                DateTime.UtcNow)))

            ' Start the server.
            Console.WriteLine("The server is starting...")
            server.Start()

            Console.WriteLine("The server is started.")
            Console.WriteLine()

            ' Let the user decide when to stop.
            Console.WriteLine("Press Enter to stop the server...")
            Console.ReadLine()

            ' Stop the server.
            Console.WriteLine("The server is stopping...")
            server.Stop()

            Console.WriteLine("The server is stopped.")
        End Sub
    End Class
End Namespace

If there is no valid initial value for the register, you can specify a "Bad" status code in its attribute data. This is illustrated in the following example.

.NET

// This example shows how to create a read-write data variable that behaves like a register, specifying initial "Bad"
// attribute data.
// You can use any OPC UA client, including our Connectivity Explorer and OpcCmd utility, to connect to the server. 
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client, server and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-OPCStudio-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

using System;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.Generic;
using OpcLabs.EasyOpc.UA.NodeSpace;

namespace UAServerDocExamples._UADataVariable
{
    partial class ReadWrite
    {
        public static void Bad()
        {
            // Instantiate the server object.
            // By default, the server will run on endpoint URL "opc.tcp://localhost:48040/".
            var server = new EasyUAServer();

            // Create a data variable that is a read-write register, defining its initial attribute data.
            // The type of the data variable (Int32, in this case) is inferred from the initial data.
            server.Add(new UADataVariable("MyVariable").ReadWrite(new UAAttributeData<int>(
                value:0,
                UACodeBits.BadNoCommunication,
                DateTime.UtcNow)));

            // Start the server.
            Console.WriteLine("The server is starting...");
            server.Start();

            Console.WriteLine("The server is started.");
            Console.WriteLine();

            // Let the user decide when to stop.
            Console.WriteLine("Press Enter to stop the server...");
            Console.ReadLine();

            // Stop the server.
            Console.WriteLine("The server is stopping...");
            server.Stop();

            Console.WriteLine("The server is stopped.");
        }
    }
}
' This example shows how to create a read-write data variable that behaves like a register, specifying initial "Bad"
' attribute data.
' You can use any OPC UA client, including our Connectivity Explorer and OpcCmd utility, to connect to the server. 
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
' OPC client and subscriber examples in VB.NET on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBNET .
' Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
' a commercial license in order to use Online Forums, and we reply to every post.

Imports System
Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.Generic
Imports OpcLabs.EasyOpc.UA.NodeSpace

Namespace _UADataVariable
    Partial Friend Class ReadWrite
        Shared Sub Bad()
            ' Instantiate the server object.
            ' By default, the server will run on endpoint URL "opc.tcp://localhost:48040/".
            Dim server = New EasyUAServer()

            ' Create a data variable that is a read-write register, defining its initial attribute data.
            ' The type of the data variable (Int32, in this case) is inferred from the initial data.
            server.Add(New UADataVariable("MyVariable").ReadWrite(New UAAttributeData(Of Integer)(
                value:=0,
                UACodeBits.BadNoCommunication,
                DateTime.UtcNow)))

            ' Start the server.
            Console.WriteLine("The server is starting...")
            server.Start()

            Console.WriteLine("The server is started.")
            Console.WriteLine()

            ' Let the user decide when to stop.
            Console.WriteLine("Press Enter to stop the server...")
            Console.ReadLine()

            ' Stop the server.
            Console.WriteLine("The server is stopping...")
            server.Stop()

            Console.WriteLine("The server is stopped.")
        End Sub
    End Class
End Namespace

The read-write registers defined by the ReadWrite method allow writing of the value, status code and timestamp. The read-write registers defined by the ReadWriteValue method only allow writing of the value. You can modify this behavior by configuring the data variable further, with the use of the Writable method. This is illustrated in the following example.

.NET

// This example shows how to create a read-write data variable that behaves like a register, and also allow writing to its
// source timestamp and status code.
// You can use any OPC UA client, including our Connectivity Explorer and OpcCmd utility, to connect to the server. 
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client, server and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-OPCStudio-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

using System;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.NodeSpace;

namespace UAServerDocExamples._UADataVariable
{
    partial class ReadWriteValue
    {
        public static void FullyWritable()
        {
            // Instantiate the server object.
            // By default, the server will run on endpoint URL "opc.tcp://localhost:48040/".
            var server = new EasyUAServer();

            // Create a data variable that is a read-write register, defining its initial value.
            // Also, allow writing to its source timestamp and status code.
            // The type of the data variable (Int32, in this case) is inferred from the initial value.
            server.Add(new UADataVariable("MyVariable").ReadWriteValue(42).Writable(true, true, true));

            // Start the server.
            Console.WriteLine("The server is starting...");
            server.Start();

            Console.WriteLine("The server is started.");
            Console.WriteLine();

            // Let the user decide when to stop.
            Console.WriteLine("Press Enter to stop the server...");
            Console.ReadLine();

            // Stop the server.
            Console.WriteLine("The server is stopping...");
            server.Stop();

            Console.WriteLine("The server is stopped.");
        }
    }
}
' This example shows how to create a read-write data variable that behaves like a register, and also allow writing to its
' source timestamp and status code.
' You can use any OPC UA client, including our Connectivity Explorer and OpcCmd utility, to connect to the server. 
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
' OPC client and subscriber examples in VB.NET on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBNET .
' Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
' a commercial license in order to use Online Forums, and we reply to every post.

Imports System
Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.NodeSpace

Namespace _UADataVariable
    Partial Friend Class ReadWriteValue
        Shared Sub FullyWritable()
            ' Instantiate the server object.
            ' By default, the server will run on endpoint URL "opc.tcp://localhost:48040/".
            Dim server = New EasyUAServer()

            ' Create a data variable that is a read-write register, defining its initial value.
            ' Also, allow writing to its source timestamp and status code.
            ' The type of the data variable (Int32, in this case) is inferred from the initial value.
            server.Add(New UADataVariable("MyVariable").ReadWriteValue(42).Writable(True, True, True))

            ' Start the server.
            Console.WriteLine("The server is starting...")
            server.Start()

            Console.WriteLine("The server is started.")
            Console.WriteLine()

            ' Let the user decide when to stop.
            Console.WriteLine("Press Enter to stop the server...")
            Console.ReadLine()

            ' Stop the server.
            Console.WriteLine("The server is stopping...")
            server.Stop()

            Console.WriteLine("The server is stopped.")
        End Sub
    End Class
End Namespace

Data Type Considerations

Because the data type model in OPC UA is not identical with the .NET type model, you need to understand what the type correspondences are, and in some cases the OPC UA data types are represented by .NET types that differ from intuitive expectations. To learn about the representation of OPC UA data types in OPC Studio, see Data Types in OPC-UA.

When you use the extension method for Data Variable Configuration, and provide an initial value (or the full UAAttributeData with the value), OPC Wizard determines the OPC UA data type of the variable (and its value rank) from the .NET type of the initial value. For example, if you use the ReadWriteValue method overload and simply pass it a System.Int32 value, the OPC UA data type (the DataTypeId Property of the data variable) will be automatically determined to be UADataTypeIds.Int32. There are cases, however, when this automatic mechanism is not suitable; if so, you can still use the extension methods for data variable configuration, but you have to specify the desired data using an overload of the extension method that has extra argument(s) for this purpose.

Also, in OPC UA, there is a ByteString type. According to newer OPC UA specifications, this type should be handled interchangeably with a single-dimensional array of Byte. When OPC Wizard methods encounter a .NET array of bytes, they prefer to choose the OPC UA ByteString data type for it, unless specified otherwise. The following example illustrates an implementation of a  writable data variable with OPC UA data type ByteString.

Example: Examples - Server OPC UA - Read-write ByteString register

Following examples illustrate how to define read-write registers of various array data types:

Example: Examples - Server OPC UA - Read-write array register

Example: Examples - Server OPC UA - Read-write 2D-array register

Example: Examples - Server OPC UA - Read-write 3D-array register

Example: Examples - Server OPC UA - Read-write bounded array register

See Also

Examples - Server OPC Unified Architecture

Installed Examples - Server Library